/*
  zuino.h - Library for zulio utility.
  Created by Guido Zuliani (zulio), January 15, 2012.
  Released into the public domain.
*/
#ifndef ZUINO_H
#define ZUINO_H

#include <Arduino.h>


const int MAX_ZELEMENTS_IN_MANAGER = 20;
const unsigned long LONG_TIME_PRESSION_MILLIS_DEFAULT = 1000UL;

class ZElement
{
  private:

  protected:
    int _PIN;
    boolean _enable;
    virtual void _reset() {_enable=true;};
  public:
    ZElement(int pin);
    
    //getter
    boolean enable() {return _enable;};
    
    //setter
    void set_enable(boolean value) {_enable = value;};
    
    virtual unsigned long refresh(unsigned long current_mills) {};
    unsigned long refresh() {return refresh(0);};
    virtual unsigned long current_millis();    
};

class ZButton : public ZElement
{
  private:
    boolean _enable_long_pression;
    unsigned long _long_time_pression_millis;
    unsigned int _prev_state;
    //unsigned int _curr_state;
    unsigned long _first_pression_millis;
    
    boolean _pressed;
    boolean _pressing;
    boolean _long_pressing;
    
  protected:
    virtual void _reset();
  public:
    ZButton(int pin);
    
    //getter
    boolean pressed() {return _pressed;};
    boolean pressing() {return _pressing;};
    boolean long_pressing() {return _long_pressing;};
    boolean enable_long_pression() {return _enable_long_pression;}
    
    //setter
    void set_enable_long_pression(boolean value) {_enable_long_pression = value;};
    
    unsigned long refresh(unsigned long current_mills);
    
};

class ZLed : public ZElement
{
  private:
    unsigned int _state;
    boolean _enable_blinking;
    boolean _blinking;
    unsigned long _bink_until_millis; 
 
  protected:
    virtual void _reset();
  public:
    ZLed(int pin);
    
    //getter
    boolean enable_blinking() {return _enable_blinking;};
    
    //setter    
    void set_enable_blinking(boolean value) {_enable_blinking = value;};
    
    unsigned long blink_for(int millisecons);
    unsigned long blink_for(int millisecons, unsigned long current_mills);
    void turn_on();
    void turn_off();
    void invert_state();
    
    unsigned long refresh(unsigned long current_mills);
};

class ZManager
{
  private:
    ZElement* _elements[MAX_ZELEMENTS_IN_MANAGER];
    int _next_element;
  public:
    ZManager();
    
    //getter
    
    //setter    
    
    boolean add(ZElement *element);
    
    unsigned long refresh(unsigned long current_millis);
    unsigned long refresh() {return refresh(0);};
};

#endif
